package jbitarrays;

import java.util.BitSet;

import javax.annotation.Nonnegative;
import javax.annotation.concurrent.NotThreadSafe;

import jbitarrays.api.InfiniteBitArray;

/**
 * An {@link InfiniteBitArray} backed by a {@link BitSet}. The stored bits
 * aren't persisted.
 */
@NotThreadSafe final class InfiniteBitSet implements InfiniteBitArray {
	private final BitSet set;

	public InfiniteBitSet(@Nonnegative int nBits) {
		if (nBits < 0) {
			throw new IllegalArgumentException("nBits >= 0");
		}
		this.set = new BitSet(nBits);
	}

	public boolean get(int index) throws IllegalArgumentException {
		Utils.checkIndex(index);
		return set.get(index);
	}

	public int getN(int index, int howMany) throws IllegalArgumentException {
		Utils.checkIndex(index);
		Utils.checkHowMany(howMany);
		int ret = 0;
		for (int i = 0; i < howMany; ++i) {
			if (set.get(index + i)) {
				ret |= 1 << i;
			}
		}
		return ret;
	}

	public void set(int index, boolean value) throws IllegalArgumentException {
		Utils.checkIndex(index);
		set.set(index, value);
	}

	public void setN(int index, int howMany, int value) throws IllegalArgumentException {
		Utils.checkIndex(index);
		Utils.checkHowMany(howMany);
		for (int i = 0; i < howMany; ++i) {
			set.set(index + i, (value & (1 << i)) != 0);
		}
	}

	@Override public String toString() {
		return set.toString();
	}
}
